﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Microsoft.Extensions.Logging;
using System.Linq;

namespace FireBillBook.Core
{
    public class FileHelper
    {
        #region 已知的字符编码
        public static byte[] Unicode = new byte[] { 0xFF, 0xFE, 0x41 };
        public static byte[] UnicodeBIG = new byte[] { 0xFE, 0xFF, 0x00 };
        public static byte[] UTF8 = new byte[] { 0xEF, 0xBB, 0xBF }; //带BOM 
        public static byte[] GB2312 = new byte[] { 0xD6, 0xA7, 0xB8 };
        #endregion

        public static void RegisterCodePages()
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
        }

        /// <summary>
        /// 自动猜测二进制的字符编码，并转换成UTF8编码
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public static Encoding AutoGuessEncoding(Stream stream, ILogger logger = null)
        {
            if(stream.Length < 3)
            {
                throw new ArgumentException("流内容长度太短，无法判断字符编码");
            }

            var byte1 = stream.ReadByte();
            var byte2 = stream.ReadByte();
            var byte3 = stream.ReadByte();

            var bytes = new byte[] { (byte)byte1, (byte)byte2, (byte)byte3 };

            logger?.LogDebug($"CurrentBytes: [{byte1}, {byte2}, {byte3}]");

            stream.Position = 0;

            if(bytes.SequenceEqual(UTF8))
            {
                return Encoding.UTF8;
            }

            if(bytes.SequenceEqual(GB2312))
            {
                return Encoding.GetEncoding("GB2312");
            }

            if (bytes.SequenceEqual(Unicode))
            {
                return Encoding.Unicode;
            }

            if (bytes.SequenceEqual(UnicodeBIG))
            {
                return Encoding.BigEndianUnicode;
            }

            throw new NotSupportedException("暂时只支持GB2312和UTF8");
        }


        /// <summary>
        /// 自动转换成默认编码
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="logger"></param>
        /// <returns></returns>
        public static Stream AutoConvert2Default(Stream stream, ILogger logger = null)
        {
            var encoding = AutoGuessEncoding(stream);

            using var sr = new StreamReader(stream, encoding);
            var stringContent = sr.ReadToEnd();

            var targetEncodingBytes = Encoding.Default.GetBytes(stringContent);

            return new MemoryStream(targetEncodingBytes);
        }
    }
}
